/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javalens.datageneration;

import javalens.astronomy.Event;
import javalens.astronomy.LightCurve;
import javalens.*;
import javalens.featurecalculators.FeatureCalculator;
import javalens.util.CalculationException;
import javalens.util.UserErrorException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author vermaak
 */
public class BinaryLensDataSetGenerator {

    private List<LightCurve> rawCurves;
    private DataSet features;
    private EventGenerator eventGenerator;
    private LightCurveGenerator curveGenerator;
    private List<FeatureCalculator> featureCalculators;
    boolean withEventParams = true;
    
    public BinaryLensDataSetGenerator(EventGenerator eventGenerator, LightCurveGenerator curveGenerator, boolean withEventParams) {
        this.eventGenerator = eventGenerator;
        this.curveGenerator = curveGenerator;
        this.featureCalculators = new ArrayList<FeatureCalculator>();
        this.rawCurves = new ArrayList<LightCurve>();
        this.features = new DataSet();
        this.withEventParams = withEventParams;
    }
    
    public void addFeatureCalculator(FeatureCalculator calc) {
        featureCalculators.add(calc);
    }
    
    private String[] getHeaders() {
        List<String> all = new ArrayList<String>();
        for (FeatureCalculator calc : featureCalculators) {
            all.addAll(Arrays.asList(calc.getHeaders()));
        }
        // add in event params too, if requested
        if (withEventParams) {
            all.addAll(Arrays.asList((new Event(0,0,0,0)).getHeaders()));
        }
        return all.toArray(new String[all.size()]);
    }
    
    public void run(int nSamples) throws UserErrorException {
        // set the headers for the features data set
        features.setHeaders(getHeaders());
        for (int i=0;i<nSamples;++i) {
            try {
                List<Double> valueList = new ArrayList<Double>();
                Event evt = eventGenerator.next();
                LightCurve curve = curveGenerator.next(evt);
                rawCurves.add(curve);
                // now calculate all the features and add them into a list
                for (FeatureCalculator calc : featureCalculators) {
                    double[] values = calc.getValues(curve);
                    for (double d : values) {
                        valueList.add(d);
                    }
                }
                // add in event values if requested
                if (withEventParams) {
                    double[] eventValues = evt.getValues();
                    for (double d : eventValues) {
                        valueList.add(d);
                    }
                }
                // and finally, complete the row of features in the DataSet
                double[] all = new double[valueList.size()];
                for (int j=0;j<valueList.size();++j) {
                    all[j] = valueList.get(j);
                }
                features.addRow(all);
            } catch (CalculationException ex) {
                Logger.getLogger(BinaryLensDataSetGenerator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public List<LightCurve> getRawCurves() {
        return rawCurves;
    }

    public DataSet getFeatures() {
        return features;
    }
    
}
